// 字符串
let myName: string = 'coderzrf';

// 数值
let age: number = 23;

// 布尔
let isBoy: boolean = true;

// 数组
let hobbies: (string | number)[] = [];
hobbies.push('basketball', 1024)
let hobbies2: Array<string | number> = [];
hobbies2.push('football', 2048)

// 元组 
// 与数组的区别在于元素在数组位置的类型是固定的
let tuple: [string, boolean] = ['handsome', true];

//对象
// 1.不限制值类型
let user: object;
user = []
user = new Object()
user = Object.prototype
user = { name: 'coderzrf' }
// 2.限制值类型
let user2: { name: string, age: number, student?: boolean }; //属性后面跟上? 用来指定 url 为可选值，这样的属性是非必填项
user2 = {
  name: 'coderzrf',
  age: 22,
}

// any
// 使用 any 指包含所有值的顶部类型，所以any不进行类型检查，等于关闭了 TS 对该变量的严格类型校验
let array; //let array: any
let user3: {
  name: any,
  age: any
}

// unknown
/* 
* unknown 用于表示未知的类型
* 与 any 的区别是 any 不进行 TS 校验，unknown 类型要安全得多，会进行 TS 的类型检查
* 使用 unknown 类型时一般需要 as 类型断言来转换类型
*/
let info1: any = 'info1';
let info2: unknown = 'info2';

let a: string = info1;
// let b: string = info2 报错: 'unknown'未知类型不能赋值给'string'类型
// 借助as断言
let b: string = info2 as string;
// 借助unknown做个中间层转换
let nn: string = '1024';
let parsedNn: number = nn as unknown as number

// void 
// void类型的值为null或undefined,常用于对函数返回值类型
// 严格模式下只能是 undefined
function foo(): void {
  return;
}

// nerver
// never 是永远不会结束的函数，所以也不会有返回值
function foo2(): never {
  throw new Error("出错了")
}

// null & undefined
// 当配置项启用 strictNullChecks 时，null 与 undefined 只能赋值给 void、null、undefined 类型
let myNull: null = null;
let myUndefined: undefined = undefined;

// 函数
let func2: Function;
func2 = () => 'isFunction'

// 函数参数及返回值
function sum(a: number, b: number, ratio?: number): number {
  return a + b;
}
let sum2 = (a: number, b: number, ratio?: number): number => a + b


// 剩余参数
let sumAll = (...args: number[]): number => {
  return args.reduce((s, n) => s + n, 0)
}


// 函数定义
let func3: (a: number, b: number) => number

// type
type userType = {
  name: string;
  age: number
}
type addUserFunc = (user: userType) => boolean

let addUser: addUserFunc = (u: userType): boolean => {
  console.log("添加了用户");
  return true;

}